﻿using DataModels.Dto;
using DataModels.Dto.ServiceDayService;
using DataModels.Entities.AuthCore;
using DataModels.Entities.Bill;
using DataModels.Entities.ServiceDay;
using SqlSugar;
using System.Runtime.Intrinsics.Arm;
using static DataModels.Enums.GeneralEnum;

namespace Services.ServiceDay
{
    public class ServiceDayService(SqlSugarClient db) : BaseService(db)
    {
        /// <summary>
        /// 获取分数
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseModel> GetPoints()
        {
            ServiceDayPoints sdp = await db.Queryable<ServiceDayPoints>().Where(sdp => sdp.UserUUID == UserUUID).FirstAsync();
            if (sdp == null)
            {
                return Success(0);
            } else
            {
                return Success(sdp.Points);
            }
        }

        /// <summary>
        /// 获取活动列表
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseModel> GetServiceDayPointsActivities()
        {
            var sdpa = await db.Queryable<ServiceDayPointsActivities>()
                           .Where(sdpa => sdpa.Status == Status.Enable)
                           .Where(sdpa => sdpa.IsDeleted == Status.Disable)
                           .Where(sdpa => sdpa.EndTime == null || sdpa.EndTime > DateTime.Now)
                           .Select(sdpa => new ServiceDayServiceDto
                           {
                               UUID = sdpa.UUID,
                               Title = sdpa.Title,
                               Description = sdpa.Description,
                               Points = sdpa.Points,
                               LimitParticipationCount = sdpa.LimitParticipationCount,
                               EndTime = sdpa.EndTime
                           })
                           .ToListAsync();

            List<Guid> sdpauuids = [.. sdpa.Select(x => x.UUID)];

            var sdpap = await db.Queryable<ServiceDayPointsActivityParticipation>()
                .Where(sdpap => sdpap.CreateUserUUID == UserUUID)
                .Where(sdpap => sdpauuids.Contains(sdpap.ServiceDayPointsActivitiesUUID))
                .GroupBy(sdpap => sdpap.ServiceDayPointsActivitiesUUID)
                .Select(sdpap => new
                {
                    ActivityId = sdpap.ServiceDayPointsActivitiesUUID,
                    ParticipationCount = SqlFunc.AggregateCount(sdpap.UUID)
                })
                .ToListAsync();

            foreach (var item in sdpa)
            {
                var participation = sdpap.FirstOrDefault(x => x.ActivityId == item.UUID);
                if (participation != null)
                {
                    item.JoinCount = participation.ParticipationCount;
                }
            }

            return Success(sdpa);
        }

        /// <summary>
        ///  参与服务日积分活动
        /// </summary>
        /// <param name="ServiceDayPointsActivitiesUUID"></param>
        /// <returns></returns>
        public async Task<ResponseModel> JoinServiceDayPointsActivities(Guid ServiceDayPointsActivitiesUUID)
        {
            try
            {
                await db.BeginTranAsync();
                ServiceDayPointsActivities sdpa = await db.Queryable<ServiceDayPointsActivities>()
                   .Where(sdpa => sdpa.Status == Status.Enable)
                   .Where(sdpa => sdpa.IsDeleted == Status.Disable)
                   .Where(sdpa => sdpa.EndTime == null || sdpa.EndTime > DateTime.Now)
                   .Where(sdpa => sdpa.UUID == ServiceDayPointsActivitiesUUID)
                   .FirstAsync()
                   ;
                if (sdpa == null)
                {
                    await db.RollbackTranAsync();
                    return Error("活动不存在或已结束");
                }
                List<ServiceDayPointsActivityParticipation> count = await db.Queryable<ServiceDayPointsActivityParticipation>()
                    .Where(sdpap => sdpa.UUID == sdpap.ServiceDayPointsActivitiesUUID)
                    .ToListAsync();

                if (count.Where(x => x.CreateUserUUID == UserUUID).Count() + 1 > sdpa.LimitParticipationCount)
                {
                    await db.RollbackTranAsync();
                    return Error("参与次数已达上限");
                }
                if (sdpa.TotalParticipationCount.HasValue && count.Count + 1 > sdpa.TotalParticipationCount)
                {
                    await db.RollbackTranAsync();
                    return Error("活动总参与次数已达上限");
                }

                ServiceDayPoints sdp = await db.Queryable<ServiceDayPoints>().Where(sdp => sdp.UserUUID == UserUUID).FirstAsync();

                if (sdp == null)
                {
                    sdp = new ServiceDayPoints
                    {
                        UserUUID = UserUUID,
                        Points = 0
                    };
                    await db.Insertable(sdp).ExecuteCommandAsync();
                }

                ServiceDayPointsActivityParticipation sdpap = new()
                {
                    ServiceDayPointsActivitiesUUID = sdpa.UUID,
                    ParticipationCount = sdpa.Points,
                    OriginalCount = sdpa.Points,
                    CreateUserUUID = UserUUID
                };
                sdp.Points += sdpa.Points;
                sdp.UpdateTime = DateTime.Now;

                await db.Insertable(sdpap).ExecuteCommandAsync();
                await db.Updateable(sdp).ExecuteCommandAsync();

                await db.CommitTranAsync();

                return Success("参与成功");

            }
            catch (Exception)
            {
                await db.RollbackTranAsync();
                return Error("参与失败");
            }
        }


        /// <summary>
        /// 获取服务日积分商品列表
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseModel> GetServiceDayPointsProduct()
        {
            List<GetServiceDayPointsProductDto> sdp = await db.Queryable<ServiceDayPointsProduct>()
                .Where(sdp => sdp.Status == Status.Enable)
                .Where(sdp => sdp.IsDeleted == Status.Disable)
                .Select(sdp => new GetServiceDayPointsProductDto
                {
                    UUID = sdp.UUID,
                    Image = sdp.Image,
                    Title = sdp.Title,
                    Description = sdp.Description,
                    Points = sdp.Points,
                    Count = sdp.Count,
                    LimitParticipationCount = sdp.LimitParticipationCount
                })
                .ToListAsync();

            List<Guid> sdpuuis = [.. sdp.Select(x => x.UUID)];

            var sdprr = await db.Queryable<ServiceDayPointsRedemptionRecord>()
                .Where(sdprr => sdpuuis.Contains(sdprr.ServiceDayPointsProductUUID))
                .Where(sdprr => sdprr.CreateUserUUID == UserUUID)
                .GroupBy(sdprr => sdprr.ServiceDayPointsProductUUID)
                .Select(sdprr => new
                {
                    ProductId = sdprr.ServiceDayPointsProductUUID,
                    CashAPrizeCount = SqlFunc.AggregateCount(sdprr.UUID)
                })
                .ToListAsync()
                ;
            foreach (var item in sdp)
            {
                var redemption = sdprr;
                var redemptionCount = redemption.FirstOrDefault(x => x.ProductId == item.UUID);
                if (redemptionCount != null)
                {
                    item.CashAPrizeCount = redemptionCount.CashAPrizeCount;
                }
            }

            return Success(sdp);
        }

        /// <summary>
        /// 兑换积分商品
        /// </summary>
        /// <param name="ServiceDayPointsProductUUID"></param>
        /// <returns></returns>
        public async Task<ResponseModel> CashAPrizePointProduct(Guid ServiceDayPointsProductUUID)
        {
            try
            {
                await db.BeginTranAsync();
                ServiceDayPointsProduct sdpp = await db.Queryable<ServiceDayPointsProduct>()
                    .Where(sdp => sdp.Status == Status.Enable)
                    .Where(sdp => sdp.IsDeleted == Status.Disable)
                    .Where(sdp => sdp.UUID == ServiceDayPointsProductUUID)
                    .FirstAsync()
                    ;

                if (sdpp == null)
                {
                    await db.RollbackTranAsync();
                    return Error("兑换的商品不存在或已下架");
                }
                if (sdpp.Count - 1 < 0)
                {
                    await db.RollbackTranAsync();
                    return Error("兑换的商品已售罄");
                }

                int CashAPrizeCount = await db.Queryable<ServiceDayPointsRedemptionRecord>()
                    .Where(sdprr => sdprr.ServiceDayPointsProductUUID == sdpp.UUID)
                    .Where(sdprr => sdprr.CreateUserUUID == UserUUID)
                    .CountAsync()
                    ;

                if (CashAPrizeCount + 1 > sdpp.LimitParticipationCount)
                {
                    await db.RollbackTranAsync();
                    return Error("兑换次数已达上限");
                }

                PaymentCoupon pc = await db.Queryable<PaymentCoupon>()
                    .Where(pc => pc.Status == Status.Enable)
                    .Where(pc => pc.IsDeleted == Status.Disable)
                    .FirstAsync()
                    ;

                if (pc == null)
                {
                    await db.RollbackTranAsync();
                    return Error("兑换的优惠券不存在或已下架");
                }
                if (pc.EndTime <= DateTime.Now)
                {
                    await db.RollbackTranAsync();
                    return Error("兑换的优惠券已过期");
                }


                ServiceDayPoints sdp = await db.Queryable<ServiceDayPoints>().Where(sdp => sdp.UserUUID == UserUUID).FirstAsync();
                if (sdp == null || sdp.Points - sdpp.Points < 0)
                {
                    await db.RollbackTranAsync();
                    return Error("积分不足");
                }

                ServiceDayPointsRedemptionRecord sdprr = new()
                {
                    ServiceDayPointsProductUUID = sdpp.UUID,
                    Points = sdpp.Points,
                    CreateUserUUID = UserUUID
                };

                sdp.Points -= sdpp.Points;
                sdp.UpdateTime = DateTime.Now;
                sdp.UpdateUserUUID = UserUUID;

                sdpp.Count -= 1;


                PaymentCouponMap pcm = new()
                {
                    PaymentCouponUUID = pc.UUID,
                    Price = pc.Price,
                    EndTime = pc.EndTime,
                    Type = DataModels.Enums.Bill.PaymentCouponType.Property,
                    CreateUserUUID = UserUUID
                };

                // 更新个人积分
                await db.Updateable(sdp).ExecuteCommandAsync();

                // 兑换商品
                await db.Insertable(sdprr).ExecuteCommandAsync();
                await db.Insertable(pcm).ExecuteCommandAsync();

                // 更新商品库存
                await db.Updateable(sdpp).ExecuteCommandAsync();

                await db.CommitTranAsync();
                return Success("兑换成功");
            }
            catch (Exception ex)
            {
                await db.RollbackTranAsync();
                return Error("兑换失败");
            }
        }

        /// <summary>
        /// 获取月服务日的商品
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseModel> GetProduct()
        {
            List<ServiceDayProduct> sdps = await db.Queryable<ServiceDayProduct>()
                .Where(sdp => sdp.Status == Status.Enable)
                .Where(sdp => sdp.IsDeleted == Status.Disable)
                .ToListAsync();

            return Success(sdps);
        }

        /// <summary>
        /// 记录咨询信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<ResponseModel> ProductAsk(ServiceDayProductAskAbout info)
        {
            if(UserUUID != Guid.Empty)
            {
                info.CreateUserUUID = UserUUID;
            }
            await db.Insertable(info).ExecuteCommandAsync();
            return Success();
        }
    }
}
